import { ApiResponse, get } from '@/api';

type TCommonDict = ApiResponse<'get', '/dict/field-type'>;
type Options = { label: string; value: string; disabled?: boolean }[];

const dirtToOptions = (dirt: TCommonDict) => {
  return dirt
    .filter((item) => item.enable === true)
    .map((item) => {
      return {
        label: item.dictName!,
        value: item.dictCode! as unknown as string,
        disabled: item.enable !== true
      };
    });
};

/** 字段类型字典 */
const fieldTypeOptionsAtom = atom<Options>({
  key: 'fieldType',
  default: []
});
const fieldTypeMapSelector = selector<Record<string, string>>({
  key: 'fieldTypeMapSelector',
  get({ get }) {
    const fieldType = get(fieldTypeOptionsAtom);
    return fieldType.reduce(
      (obj, item) => {
        obj[item.value as unknown as string] = item.label!;
        return obj;
      },
      {} as Record<string, string>
    );
  }
});
/** 操作符字典 */
const dictOperatorOptionsAtom = atom<Options>({
  key: 'dictOperator',
  default: []
});
/** 集合操作符字典 */
const dictListOperatorOptionsAtom = atom<Options>({
  key: 'dictListOperator',
  default: []
});
/** 计算类型字典 */
const dictCalcTypeOptionsAtom = atom<Options>({
  key: 'dictCalcType',
  default: []
});
/** 连接类型字典 */
const dictConjOptionsAtom = atom<Options>({
  key: 'dictConj',
  default: []
});
/** 字段作用域字典 */
const dictFieldScopeOptionsAtom = atom<Options>({
  key: 'dictFieldScope',
  default: []
});

const dictFieldScopeMapSelector = selector<Record<string, string>>({
  key: 'dictFieldScopeMapSelector',
  get({ get }) {
    const dictFieldScope = get(dictFieldScopeOptionsAtom);
    return dictFieldScope.reduce(
      (obj, item) => {
        obj[item.value as unknown as string] = item.label!;
        return obj;
      },
      {} as Record<string, string>
    );
  }
});
/** 序列号类型字典 */
const dictSerializeTypeOptionsAtom = atom<Options>({
  key: 'dictSerializeType',
  default: []
});
/** 节点类型字典 */
const dictNodeTypeOptionsAtom = atom<Options>({
  key: 'dictNodeType',
  default: []
});
/** 聚合函数字典 */
const dictAggFuncOptionsAtom = atom<Options>({
  key: 'dictAggFunc',
  default: []
});

/** 获取API解析模板字典 */
const dictApiTemplateOptionsAtom = atom<Options>({
  key: 'dictApiTemplate',
  default: []
});
const systemVarsOptionsAtom = atom<ApiResponse<'get', '/flow/systemVars'>>({
  key: 'systemVars',
  default: []
});
/** 决策流执行状态字典 */
const dictExecStatusOptionsAtom = atom<Options>({
  key: 'dictExecStatus',
  default: []
});

const dictExecStatusMapSelector = selector<Record<string, string>>({
  key: 'dictExecStatusMapSelector',
  get({ get }) {
    const dictExecStatus = get(dictExecStatusOptionsAtom);
    return dictExecStatus.reduce(
      (obj, item) => {
        obj[item.value as unknown as string] = item.label!;
        return obj;
      },
      {} as Record<string, string>
    );
  }
});

// 字典表数据缓存
export const useDictStore = () => {
  const [fieldTypeOptions, setFieldType] = useRecoilState(fieldTypeOptionsAtom);
  const [dictOperatorOptions, setDictOperator] = useRecoilState(dictOperatorOptionsAtom);
  const [dictListOperatorOptions, setDictListOperator] = useRecoilState(dictListOperatorOptionsAtom);
  const [dictCalcTypeOptions, setDictCalcType] = useRecoilState(dictCalcTypeOptionsAtom);
  const [dictConjOptions, setDictConj] = useRecoilState(dictConjOptionsAtom);
  const [dictFieldScopeOptions, setDictFieldScope] = useRecoilState(dictFieldScopeOptionsAtom);
  const [dictSerializeTypeOptions, setDictSerializeType] = useRecoilState(dictSerializeTypeOptionsAtom);
  const [dictNodeTypeOptions, setDictNodeType] = useRecoilState(dictNodeTypeOptionsAtom);
  const [dictAggFuncOptions, setDictAggFunc] = useRecoilState(dictAggFuncOptionsAtom);
  const [dictApiTemplateOptions, setDictApiTemplate] = useRecoilState(dictApiTemplateOptionsAtom);
  const [systemVars, setSystemVars] = useRecoilState(systemVarsOptionsAtom);
  const [dictExecStatusOptions, setDictExecStatus] = useRecoilState(dictExecStatusOptionsAtom);
  const dictExecStatusMap = useRecoilValue(dictExecStatusMapSelector);
  const dictFieldScopeMap = useRecoilValue(dictFieldScopeMapSelector);
  const fieldTypeMap = useRecoilValue(fieldTypeMapSelector);

  const systemVarsOptions = useMemo(() => {
    return systemVars.map((item) => {
      return {
        label: item.varLabel,
        value: item.varName,
        varType: item.varType as string
      };
    });
  }, [systemVars]);

  const fetchDictData = useCallback(() => {
    get('/dict/all', {} as never).then((res) => {
      get('/flow/systemVars', {} as never).then((vars) => {
        setFieldType(dirtToOptions(res.fieldTypes || []));
        setDictOperator(dirtToOptions(res.operators || []));
        setDictListOperator(dirtToOptions(res.listOperators || []));
        setDictCalcType(dirtToOptions(res.calcTypes || []));
        setDictConj(dirtToOptions(res.conjs || []));
        setDictFieldScope(dirtToOptions(res.fieldScopes || []));
        setDictSerializeType(dirtToOptions(res.serializeTypes || []));
        setDictNodeType(dirtToOptions(res.nodeTypes || []));
        setDictAggFunc(dirtToOptions(res.aggFuncs || []));
        setDictApiTemplate(dirtToOptions(res.apiTemplates || []));
        setDictExecStatus(dirtToOptions(res.execStatuses || []));
        setSystemVars(vars);
      });
    });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return {
    fetchDictData,
    fieldTypeOptions,
    dictOperatorOptions,
    dictListOperatorOptions,
    dictCalcTypeOptions,
    dictConjOptions,
    dictFieldScopeOptions,
    dictSerializeTypeOptions,
    dictNodeTypeOptions,
    dictAggFuncOptions,
    dictApiTemplateOptions,
    dictExecStatusOptions,
    systemVars,
    systemVarsOptions,
    dictExecStatusMap,
    dictFieldScopeMap,
    fieldTypeMap
  };
};
